/*
 ------------------------------------------------------------------------------
 Copyright (C) 2006-2007 Team Blur.

 This file is part of the Quantum Engine source code.

 The Quantum Engine source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The Quantum Engine source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the Quantum Engine source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


#include "../ed_local.h"
#include "../../win32/win_local.h"


#define REVERB_EDITOR_WINDOW_NAME		ENGINE_NAME " Reverb Editor"
#define REVERB_EDITOR_WINDOW_CLASS		ENGINE_NAME " ReverbEditorWnd"
#define REVERB_EDITOR_WINDOW_STYLE		(WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)

typedef enum {
	REVERB_PRESET_GENERIC,
	REVERB_PRESET_PADDEDCELL,
	REVERB_PRESET_ROOM,
	REVERB_PRESET_BATHROOM,
	REVERB_PRESET_LIVINGROOM,
	REVERB_PRESET_STONEROOM,
	REVERB_PRESET_AUDITORIUM,
	REVERB_PRESET_CONCERTHALL,
	REVERB_PRESET_CAVE,
	REVERB_PRESET_ARENA,
	REVERB_PRESET_HANGAR,
	REVERB_PRESET_CARPETTEDHALLWAY,
	REVERB_PRESET_HALLWAY,
	REVERB_PRESET_STONECORRIDOR,
	REVERB_PRESET_ALLEY,
	REVERB_PRESET_FOREST,
	REVERB_PRESET_CITY,
	REVERB_PRESET_MOUNTAINS,
	REVERB_PRESET_QUARRY,
	REVERB_PRESET_PLAIN,
	REVERB_PRESET_PARKINGLOT,
	REVERB_PRESET_SEWERPIPE,
	REVERB_PRESET_UNDERWATER,
	REVERB_PRESET_DRUGGED,
	REVERB_PRESET_DIZZY,
	REVERB_PRESET_PSYCHOTIC
} reverbPreset_t;

static const char *			ed_reverbNames[26] = {
	"Generic",
	"Padded Cell",
	"Room",
	"Bathroom",
	"Living Room",
	"Stone Room",
	"Auditorium",
	"Concert Hall",
	"Cave",
	"Arena",
	"Hangar",
	"Carpetted Hallway",
	"Hallway",
	"Stone Corridor",
	"Alley",
	"Forest",
	"City",
	"Mountains",
	"Quarry",
	"Plain",
	"Parking Lot",
	"Sewer Pipe",
	"Underwater",
	"Drugged",
	"Dizzy",
	"Psychotic"
};

static reverbProperties_t	ed_reverbProperties[26] = {
	{1.0f, 1.0f, 0.32f, 0.89f, 1.0f, 1.49f, 0.83f, 1.0f, true, 0.05f, 0.007f, odVec3(0.0f, 0.0f, 0.0f), 1.26f, 0.011f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{0.1715f, 1.0f, 0.32f, 0.001f, 1.0f, 0.17f, 0.1f, 1.0f, true, 0.250035f, 0.001f, odVec3(0.0f, 0.0f, 0.0f), 1.26911f, 0.002f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{0.428687f, 1.0f, 0.32f, 0.592925f, 1.0f, 0.4f, 0.83f, 1.0f, true, 0.150314f, 0.002f, odVec3(0.0f, 0.0f, 0.0f), 1.06292f, 0.003f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{0.1715f, 1.0f, 0.32f, 0.251189f, 1.0f, 1.49f, 0.54f, 1.0f, true, 0.653131f, 0.007f, odVec3(0.0f, 0.0f, 0.0f), 3.27341f, 0.011f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{0.976563f, 1.0f, 0.32f, 0.001f, 1.0f, 0.5f, 0.1f, 1.0f, true, 0.205116f, 0.003f, odVec3(0.0f, 0.0f, 0.0f), 0.280543f, 0.004f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{1.0f, 1.0f, 0.32f, 0.707946f, 1.0f, 2.31f, 0.64f, 1.0f, true, 0.441062f, 0.012f, odVec3(0.0f, 0.0f, 0.0f), 1.10027f, 0.017f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{1.0f, 1.0f, 0.32f, 0.578096f, 1.0f, 4.32f, 0.59f, 1.0f, true, 0.403181f, 0.02f, odVec3(0.0f, 0.0f, 0.0f), 0.716968f, 0.03f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{1.0f, 1.0f, 0.32f, 0.562341f, 1.0f, 3.92f, 0.7f, 1.0f, true, 0.242661f, 0.02f, odVec3(0.0f, 0.0f, 0.0f), 0.9977f, 0.029f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{1.0f, 1.0f, 0.32f, 1.0f, 1.0f, 2.91f, 1.3f, 1.0f, false, 0.500035f, 0.015f, odVec3(0.0f, 0.0f, 0.0f), 0.706318f, 0.022f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{1.0f, 1.0f, 0.32f, 0.447713f, 1.0f, 7.24f, 0.33f, 1.0f, true, 0.261216f, 0.02f, odVec3(0.0f, 0.0f, 0.0f), 1.01859f, 0.03f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{1.0f, 1.0f, 0.32f, 0.32f, 1.0f, 10.05f, 0.23f, 1.0f, true, 0.500035f, 0.02f, odVec3(0.0f, 0.0f, 0.0f), 1.25603f, 0.03f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{0.428687f, 1.0f, 0.32f, 0.01f, 1.0f, 0.3f, 0.1f, 1.0f, true, 0.121479f, 0.002f, odVec3(0.0f, 0.0f, 0.0f), 0.153109f, 0.03f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{0.3645f, 1.0f, 0.32f, 0.707946f, 1.0f, 1.49f, 0.59f, 1.0f, true, 0.245754f, 0.007f, odVec3(0.0f, 0.0f, 0.0f), 1.6615f, 0.011f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{1.0f, 1.0f, 0.32f, 0.761202f, 1.0f, 2.7f, 0.79f, 1.0f, true, 0.247172f, 0.013f, odVec3(0.0f, 0.0f, 0.0f), 1.5758f, 0.02f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{1.0f, 0.3f, 0.32f, 0.732825f, 1.0f, 1.49f, 0.86f, 1.0f, true, 0.250035f, 0.007f, odVec3(0.0f, 0.0f, 0.0f), 0.995405f, 0.011f, odVec3(0.0f, 0.0f, 0.0f), 0.125f, 0.95f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{1.0f, 0.3f, 0.32f, 0.0223872f, 1.0f, 1.49f, 0.54f, 1.0f, true, 0.0524807f, 0.162f, odVec3(0.0f, 0.0f, 0.0f), 0.768245f, 0.088f, odVec3(0.0f, 0.0f, 0.0f), 0.125f, 1.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{1.0f, 0.5f, 0.32f, 0.398107f, 1.0f, 1.49f, 0.67f, 1.0f, true, 0.0730298f, 0.007f, odVec3(0.0f, 0.0f, 0.0f), 0.142725f, 0.011f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{1.0f, 0.27f, 0.32f, 0.0562341f, 1.0f, 1.49f, 0.21f, 1.0f, false, 0.040738f, 0.3f, odVec3(0.0f, 0.0f, 0.0f), 0.191867f, 0.1f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 1.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{1.0f, 1.0f, 0.32f, 0.32f, 1.0f, 1.49f, 0.83f, 1.0f, true, 0.0f, 0.061f, odVec3(0.0f, 0.0f, 0.0f), 1.77828f, 0.025f, odVec3(0.0f, 0.0f, 0.0f), 0.125f, 0.7f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{1.0f, 0.21f, 0.32f, 0.1f, 1.0f, 1.49f, 0.5f, 1.0f, true, 0.058479f, 0.179f, odVec3(0.0f, 0.0f, 0.0f), 0.108893f, 0.1f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 1.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{1.0f, 1.0f, 0.32f, 1.0f, 1.0f, 1.65f, 1.5f, 1.0f, false, 0.208209f, 0.008f, odVec3(0.0f, 0.0f, 0.0f), 0.265155f, 0.012f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{0.307063f, 0.8f, 0.32f, 0.32f, 1.0f, 2.81f, 0.14f, 1.0f, true, 1.6387f, 0.014f, odVec3(0.0f, 0.0f, 0.0f), 3.24713f, 0.021f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 0.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{0.3645f, 1.0f, 0.32f, 0.01f, 1.0f, 1.49f, 0.1f, 1.0f, true, 0.596348f, 0.007f, odVec3(0.0f, 0.0f, 0.0f), 7.07946f, 0.011f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 1.18f, 0.348f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{0.428687f, 0.5f, 0.32f, 1.0f, 1.0f, 8.39f, 1.39f, 1.0f, false, 0.875992f, 0.002f, odVec3(0.0f, 0.0f, 0.0f), 3.10814f, 0.03f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 0.25f, 1.0f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{0.3645f, 0.6f, 0.32f, 0.630957f, 1.0f, 17.23f, 0.56f, 1.0f, false, 0.139155f, 0.02f, odVec3(0.0f, 0.0f, 0.0f), 0.493742f, 0.03f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 1.0f, 0.81f, 0.31f, 5000.0f, 250.0f, 0.994f, 0.0f},
	{0.0625f, 0.5f, 0.32f, 0.840427f, 1.0f, 7.56f, 0.91f, 1.0f, false, 0.486407f, 0.02f, odVec3(0.0f, 0.0f, 0.0f), 2.43781f, 0.03f, odVec3(0.0f, 0.0f, 0.0f), 0.25f, 0.0f, 4.0f, 1.0f, 5000.0f, 250.0f, 0.994f, 0.0f}
};

typedef struct {
	bool					enabled;

	reverbCallbacks_t		callbacks;

	int						editIndex;
	reverbProperties_t		editProperties;

	// Window stuff
	HWND					hWnd;

	HWND					hWndFrame1;
	HWND					hWndFrame2;
	HWND					hWndFrame3;
	HWND					hWndFrame4;
	HWND					hWndFrame5;
	HWND					hWndFrame6;
	HWND					hWndFrame7;
	HWND					hWndFrame8;
	HWND					hWndFrame9;

	HWND					hWndArea;
	HWND					hWndAreaValue;

	HWND					hWndPreset;
	HWND					hWndPresetValue;

	HWND					hWndDensity;
	HWND					hWndDensityValue;

	HWND					hWndDiffusion;
	HWND					hWndDiffusionValue;

	HWND					hWndGain;
	HWND					hWndGainValue;

	HWND					hWndGainHF;
	HWND					hWndGainHFValue;

	HWND					hWndGainLF;
	HWND					hWndGainLFValue;

	HWND					hWndDecayTime;
	HWND					hWndDecayTimeValue;

	HWND					hWndDecayHFRatio;
	HWND					hWndDecayHFRatioValue;

	HWND					hWndDecayLFRatio;
	HWND					hWndDecayLFRatioValue;

	HWND					hWndDecayHFLimit;

	HWND					hWndReflectionsGain;
	HWND					hWndReflectionsGainValue;

	HWND					hWndReflectionsDelay;
	HWND					hWndReflectionsDelayValue;

	HWND					hWndReflectionsPan;
	HWND					hWndReflectionsPanX;
	HWND					hWndReflectionsPanY;
	HWND					hWndReflectionsPanZ;
	HWND					hWndReflectionsPanXValue;
	HWND					hWndReflectionsPanYValue;
	HWND					hWndReflectionsPanZValue;

	HWND					hWndLateReverbGain;
	HWND					hWndLateReverbGainValue;

	HWND					hWndLateReverbDelay;
	HWND					hWndLateReverbDelayValue;

	HWND					hWndLateReverbPan;
	HWND					hWndLateReverbPanX;
	HWND					hWndLateReverbPanY;
	HWND					hWndLateReverbPanZ;
	HWND					hWndLateReverbPanXValue;
	HWND					hWndLateReverbPanYValue;
	HWND					hWndLateReverbPanZValue;

	HWND					hWndEchoTime;
	HWND					hWndEchoTimeValue;

	HWND					hWndEchoDepth;
	HWND					hWndEchoDepthValue;

	HWND					hWndModulationTime;
	HWND					hWndModulationTimeValue;

	HWND					hWndModulationDepth;
	HWND					hWndModulationDepthValue;

	HWND					hWndHFReference;
	HWND					hWndHFReferenceValue;

	HWND					hWndLFReference;
	HWND					hWndLFReferenceValue;

	HWND					hWndAirAbsorptionGainHF;
	HWND					hWndAirAbsorptionGainHFValue;

	HWND					hWndRoomRolloffFactor;
	HWND					hWndRoomRolloffFactorValue;

	HWND					hWndApply;
	HWND					hWndReset;
	HWND					hWndClear;
	HWND					hWndSave;

	HFONT					hFont;
} reverbEditor_t;

static reverbEditor_t		ed_reverbEditor;


/*
 ==================
 ED_ApplyReverbProperties
 ==================
*/
static void ED_ApplyReverbProperties (void){

	reverbProperties_t	properties;
	char				string[32];

	if (!ed_reverbEditor.enabled)
		return;

	// Read the controls
	if (GetWindowText(ed_reverbEditor.hWndDensityValue, string, sizeof(string)))
		properties.density = Str_ToFloat(string);
	else
		properties.density = ed_reverbEditor.editProperties.density;

	if (GetWindowText(ed_reverbEditor.hWndDiffusionValue, string, sizeof(string)))
		properties.diffusion = Str_ToFloat(string);
	else
		properties.diffusion = ed_reverbEditor.editProperties.diffusion;

	if (GetWindowText(ed_reverbEditor.hWndGainValue, string, sizeof(string)))
		properties.gain = Str_ToFloat(string);
	else
		properties.gain = ed_reverbEditor.editProperties.gain;

	if (GetWindowText(ed_reverbEditor.hWndGainHFValue, string, sizeof(string)))
		properties.gainHF = Str_ToFloat(string);
	else
		properties.gainHF = ed_reverbEditor.editProperties.gainHF;

	if (GetWindowText(ed_reverbEditor.hWndGainLFValue, string, sizeof(string)))
		properties.gainLF = Str_ToFloat(string);
	else
		properties.gainLF = ed_reverbEditor.editProperties.gainLF;

	if (GetWindowText(ed_reverbEditor.hWndDecayTimeValue, string, sizeof(string)))
		properties.decayTime = Str_ToFloat(string);
	else
		properties.decayTime = ed_reverbEditor.editProperties.decayTime;

	if (GetWindowText(ed_reverbEditor.hWndDecayHFRatioValue, string, sizeof(string)))
		properties.decayHFRatio = Str_ToFloat(string);
	else
		properties.decayHFRatio = ed_reverbEditor.editProperties.decayHFRatio;

	if (GetWindowText(ed_reverbEditor.hWndDecayLFRatioValue, string, sizeof(string)))
		properties.decayLFRatio = Str_ToFloat(string);
	else
		properties.decayLFRatio = ed_reverbEditor.editProperties.decayLFRatio;

	if (SendMessage(ed_reverbEditor.hWndDecayHFLimit, BM_GETCHECK, 0, 0) == BST_CHECKED)
		properties.decayHFLimit = true;
	else
		properties.decayHFLimit = false;

	if (GetWindowText(ed_reverbEditor.hWndReflectionsGainValue, string, sizeof(string)))
		properties.reflectionsGain = Str_ToFloat(string);
	else
		properties.reflectionsGain = ed_reverbEditor.editProperties.reflectionsGain;

	if (GetWindowText(ed_reverbEditor.hWndReflectionsDelayValue, string, sizeof(string)))
		properties.reflectionsDelay = Str_ToFloat(string);
	else
		properties.reflectionsDelay = ed_reverbEditor.editProperties.reflectionsDelay;

	if (GetWindowText(ed_reverbEditor.hWndReflectionsPanXValue, string, sizeof(string)))
		properties.reflectionsPan[0] = Str_ToFloat(string);
	else
		properties.reflectionsPan[0] = ed_reverbEditor.editProperties.reflectionsPan[0];

	if (GetWindowText(ed_reverbEditor.hWndReflectionsPanYValue, string, sizeof(string)))
		properties.reflectionsPan[1] = Str_ToFloat(string);
	else
		properties.reflectionsPan[1] = ed_reverbEditor.editProperties.reflectionsPan[1];

	if (GetWindowText(ed_reverbEditor.hWndReflectionsPanZValue, string, sizeof(string)))
		properties.reflectionsPan[2] = Str_ToFloat(string);
	else
		properties.reflectionsPan[2] = ed_reverbEditor.editProperties.reflectionsPan[2];

	if (GetWindowText(ed_reverbEditor.hWndLateReverbGainValue, string, sizeof(string)))
		properties.lateReverbGain = Str_ToFloat(string);
	else
		properties.lateReverbGain = ed_reverbEditor.editProperties.lateReverbGain;

	if (GetWindowText(ed_reverbEditor.hWndLateReverbDelayValue, string, sizeof(string)))
		properties.lateReverbDelay = Str_ToFloat(string);
	else
		properties.lateReverbDelay = ed_reverbEditor.editProperties.lateReverbDelay;

	if (GetWindowText(ed_reverbEditor.hWndLateReverbPanXValue, string, sizeof(string)))
		properties.lateReverbPan[0] = Str_ToFloat(string);
	else
		properties.lateReverbPan[0] = ed_reverbEditor.editProperties.lateReverbPan[0];

	if (GetWindowText(ed_reverbEditor.hWndLateReverbPanYValue, string, sizeof(string)))
		properties.lateReverbPan[1] = Str_ToFloat(string);
	else
		properties.lateReverbPan[1] = ed_reverbEditor.editProperties.lateReverbPan[1];

	if (GetWindowText(ed_reverbEditor.hWndLateReverbPanZValue, string, sizeof(string)))
		properties.lateReverbPan[2] = Str_ToFloat(string);
	else
		properties.lateReverbPan[2] = ed_reverbEditor.editProperties.lateReverbPan[2];

	if (GetWindowText(ed_reverbEditor.hWndEchoTimeValue, string, sizeof(string)))
		properties.echoTime = Str_ToFloat(string);
	else
		properties.echoTime = ed_reverbEditor.editProperties.echoTime;

	if (GetWindowText(ed_reverbEditor.hWndEchoDepthValue, string, sizeof(string)))
		properties.echoDepth = Str_ToFloat(string);
	else
		properties.echoDepth = ed_reverbEditor.editProperties.echoDepth;

	if (GetWindowText(ed_reverbEditor.hWndModulationTimeValue, string, sizeof(string)))
		properties.modulationTime = Str_ToFloat(string);
	else
		properties.modulationTime = ed_reverbEditor.editProperties.modulationTime;

	if (GetWindowText(ed_reverbEditor.hWndModulationDepthValue, string, sizeof(string)))
		properties.modulationDepth = Str_ToFloat(string);
	else
		properties.modulationDepth = ed_reverbEditor.editProperties.modulationDepth;

	if (GetWindowText(ed_reverbEditor.hWndHFReferenceValue, string, sizeof(string)))
		properties.hfReference = Str_ToFloat(string);
	else
		properties.hfReference = ed_reverbEditor.editProperties.hfReference;

	if (GetWindowText(ed_reverbEditor.hWndLFReferenceValue, string, sizeof(string)))
		properties.lfReference = Str_ToFloat(string);
	else
		properties.lfReference = ed_reverbEditor.editProperties.lfReference;

	if (GetWindowText(ed_reverbEditor.hWndAirAbsorptionGainHFValue, string, sizeof(string)))
		properties.airAbsorptionGainHF = Str_ToFloat(string);
	else
		properties.airAbsorptionGainHF = ed_reverbEditor.editProperties.airAbsorptionGainHF;

	if (GetWindowText(ed_reverbEditor.hWndRoomRolloffFactorValue, string, sizeof(string)))
		properties.roomRolloffFactor = Str_ToFloat(string);
	else
		properties.roomRolloffFactor = ed_reverbEditor.editProperties.roomRolloffFactor;

	// Update the properties
	ed_reverbEditor.callbacks.Update(ed_reverbEditor.editIndex, &properties);
}

/*
 ==================
 ED_ResetReverbProperties
 ==================
*/
static void ED_ResetReverbProperties (void){

	int		i;

	if (!ed_reverbEditor.enabled)
		return;

	// Update the controls
	for (i = 0; i < 26; i++){
		if (ed_reverbEditor.editProperties.density != ed_reverbProperties[i].density)
			continue;
		if (ed_reverbEditor.editProperties.diffusion != ed_reverbProperties[i].diffusion)
			continue;
		if (ed_reverbEditor.editProperties.gain != ed_reverbProperties[i].gain)
			continue;
		if (ed_reverbEditor.editProperties.gainHF != ed_reverbProperties[i].gainHF)
			continue;
		if (ed_reverbEditor.editProperties.gainLF != ed_reverbProperties[i].gainLF)
			continue;
		if (ed_reverbEditor.editProperties.decayTime != ed_reverbProperties[i].decayTime)
			continue;
		if (ed_reverbEditor.editProperties.decayHFRatio != ed_reverbProperties[i].decayHFRatio)
			continue;
		if (ed_reverbEditor.editProperties.decayLFRatio != ed_reverbProperties[i].decayLFRatio)
			continue;
		if (ed_reverbEditor.editProperties.decayHFLimit != ed_reverbProperties[i].decayHFLimit)
			continue;
		if (ed_reverbEditor.editProperties.reflectionsGain != ed_reverbProperties[i].reflectionsGain)
			continue;
		if (ed_reverbEditor.editProperties.reflectionsDelay != ed_reverbProperties[i].reflectionsDelay)
			continue;
		if (ed_reverbEditor.editProperties.reflectionsPan != ed_reverbProperties[i].reflectionsPan)
			continue;
		if (ed_reverbEditor.editProperties.lateReverbGain != ed_reverbProperties[i].lateReverbGain)
			continue;
		if (ed_reverbEditor.editProperties.lateReverbDelay != ed_reverbProperties[i].lateReverbDelay)
			continue;
		if (ed_reverbEditor.editProperties.lateReverbPan != ed_reverbProperties[i].lateReverbPan)
			continue;
		if (ed_reverbEditor.editProperties.echoTime != ed_reverbProperties[i].echoTime)
			continue;
		if (ed_reverbEditor.editProperties.echoDepth != ed_reverbProperties[i].echoDepth)
			continue;
		if (ed_reverbEditor.editProperties.modulationTime != ed_reverbProperties[i].modulationTime)
			continue;
		if (ed_reverbEditor.editProperties.modulationDepth != ed_reverbProperties[i].modulationDepth)
			continue;
		if (ed_reverbEditor.editProperties.hfReference != ed_reverbProperties[i].hfReference)
			continue;
		if (ed_reverbEditor.editProperties.lfReference != ed_reverbProperties[i].lfReference)
			continue;
		if (ed_reverbEditor.editProperties.airAbsorptionGainHF != ed_reverbProperties[i].airAbsorptionGainHF)
			continue;
		if (ed_reverbEditor.editProperties.roomRolloffFactor != ed_reverbProperties[i].roomRolloffFactor)
			continue;

		break;
	}
	if (i == 26)
		SendMessage(ed_reverbEditor.hWndPresetValue, CB_SETCURSEL, (WPARAM)0, 0);
	else
		SendMessage(ed_reverbEditor.hWndPresetValue, CB_SETCURSEL, (WPARAM)(i+1), 0);

	SetWindowText(ed_reverbEditor.hWndDensityValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.density));
	SetWindowText(ed_reverbEditor.hWndDiffusionValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.diffusion));

	SetWindowText(ed_reverbEditor.hWndGainValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.gain));
	SetWindowText(ed_reverbEditor.hWndGainHFValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.gainHF));
	SetWindowText(ed_reverbEditor.hWndGainLFValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.gainLF));

	SetWindowText(ed_reverbEditor.hWndDecayTimeValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.decayTime));
	SetWindowText(ed_reverbEditor.hWndDecayHFRatioValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.decayHFRatio));
	SetWindowText(ed_reverbEditor.hWndDecayLFRatioValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.decayLFRatio));

	if (ed_reverbEditor.editProperties.decayHFLimit)
		SendMessage(ed_reverbEditor.hWndDecayHFLimit, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
	else
		SendMessage(ed_reverbEditor.hWndDecayHFLimit, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); 

	SetWindowText(ed_reverbEditor.hWndReflectionsGainValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.reflectionsGain));
	SetWindowText(ed_reverbEditor.hWndReflectionsDelayValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.reflectionsDelay));
	SetWindowText(ed_reverbEditor.hWndReflectionsPanXValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.reflectionsPan[0]));
	SetWindowText(ed_reverbEditor.hWndReflectionsPanYValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.reflectionsPan[1]));
	SetWindowText(ed_reverbEditor.hWndReflectionsPanZValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.reflectionsPan[2]));

	SetWindowText(ed_reverbEditor.hWndLateReverbGainValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.lateReverbGain));
	SetWindowText(ed_reverbEditor.hWndLateReverbDelayValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.lateReverbDelay));
	SetWindowText(ed_reverbEditor.hWndLateReverbPanXValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.lateReverbPan[0]));
	SetWindowText(ed_reverbEditor.hWndLateReverbPanYValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.lateReverbPan[1]));
	SetWindowText(ed_reverbEditor.hWndLateReverbPanZValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.lateReverbPan[2]));

	SetWindowText(ed_reverbEditor.hWndEchoTimeValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.echoTime));
	SetWindowText(ed_reverbEditor.hWndEchoDepthValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.echoDepth));

	SetWindowText(ed_reverbEditor.hWndModulationTimeValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.modulationTime));
	SetWindowText(ed_reverbEditor.hWndModulationDepthValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.modulationDepth));

	SetWindowText(ed_reverbEditor.hWndHFReferenceValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.hfReference));
	SetWindowText(ed_reverbEditor.hWndLFReferenceValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.lfReference));

	SetWindowText(ed_reverbEditor.hWndAirAbsorptionGainHFValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.airAbsorptionGainHF));
	SetWindowText(ed_reverbEditor.hWndRoomRolloffFactorValue, Str_VarArgs("%g", ed_reverbEditor.editProperties.roomRolloffFactor));

	// Update the properties
	ed_reverbEditor.callbacks.Update(ed_reverbEditor.editIndex, &ed_reverbEditor.editProperties);
}

/*
 ==================
 ED_ReverbEditorWindowProc
 ==================
*/
static LRESULT CALLBACK ED_ReverbEditorWindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){

	int		result;

	switch (uMsg){
	case WM_CREATE:
		sys.hWndEditor = hWnd;

		break;
	case WM_DESTROY:
		sys.hWndEditor = NULL;

		break;
	case WM_CLOSE:
		result = MessageBox(ed_reverbEditor.hWnd, "Do you want to save the changes?", REVERB_EDITOR_WINDOW_NAME, MB_YESNOCANCEL | MB_TASKMODAL);

		switch (result){
		case IDYES:
			ED_ApplyReverbProperties();

			ed_reverbEditor.callbacks.Save();
			ed_reverbEditor.callbacks.Close();

			break;
		case IDNO:
			ED_ApplyReverbProperties();

			ed_reverbEditor.callbacks.Close();

			break;
		}

		return 0;
	case WM_COMMAND:
		if (HIWORD(wParam) == BN_CLICKED){
			if ((HWND)lParam == ed_reverbEditor.hWndApply){
				ED_ApplyReverbProperties();
				break;
			}

			if ((HWND)lParam == ed_reverbEditor.hWndReset){
				ED_ResetReverbProperties();
				break;
			}

			if ((HWND)lParam == ed_reverbEditor.hWndClear){
				result = MessageBox(ed_reverbEditor.hWnd, "Do you want to clear all reverbs?", REVERB_EDITOR_WINDOW_NAME, MB_YESNO | MB_TASKMODAL);

				if (ed_reverbEditor.enabled){
					ed_reverbEditor.editProperties = ed_reverbProperties[REVERB_PRESET_GENERIC];

					ED_ResetReverbProperties();
				}

				if (result == IDYES)
					ed_reverbEditor.callbacks.Clear();

				break;
			}

			if ((HWND)lParam == ed_reverbEditor.hWndSave){
				ED_ApplyReverbProperties();

				ed_reverbEditor.callbacks.Save();

				break;
			}
		}

		if (HIWORD(wParam) == CBN_SELCHANGE){
			if ((HWND)lParam == ed_reverbEditor.hWndPresetValue){
				result = SendMessage(ed_reverbEditor.hWndPresetValue, CB_GETCURSEL, 0, 0) - 1;

				if (result < 0 || result >= 26)
					break;

				SetWindowText(ed_reverbEditor.hWndDensityValue, Str_VarArgs("%g", ed_reverbProperties[result].density));
				SetWindowText(ed_reverbEditor.hWndDiffusionValue, Str_VarArgs("%g", ed_reverbProperties[result].diffusion));

				SetWindowText(ed_reverbEditor.hWndGainValue, Str_VarArgs("%g", ed_reverbProperties[result].gain));
				SetWindowText(ed_reverbEditor.hWndGainHFValue, Str_VarArgs("%g", ed_reverbProperties[result].gainHF));
				SetWindowText(ed_reverbEditor.hWndGainLFValue, Str_VarArgs("%g", ed_reverbProperties[result].gainLF));

				SetWindowText(ed_reverbEditor.hWndDecayTimeValue, Str_VarArgs("%g", ed_reverbProperties[result].decayTime));
				SetWindowText(ed_reverbEditor.hWndDecayHFRatioValue, Str_VarArgs("%g", ed_reverbProperties[result].decayHFRatio));
				SetWindowText(ed_reverbEditor.hWndDecayLFRatioValue, Str_VarArgs("%g", ed_reverbProperties[result].decayLFRatio));

				if (ed_reverbProperties[result].decayHFLimit)
					SendMessage(ed_reverbEditor.hWndDecayHFLimit, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
				else
					SendMessage(ed_reverbEditor.hWndDecayHFLimit, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); 

				SetWindowText(ed_reverbEditor.hWndReflectionsGainValue, Str_VarArgs("%g", ed_reverbProperties[result].reflectionsGain));
				SetWindowText(ed_reverbEditor.hWndReflectionsDelayValue, Str_VarArgs("%g", ed_reverbProperties[result].reflectionsDelay));
				SetWindowText(ed_reverbEditor.hWndReflectionsPanXValue, Str_VarArgs("%g", ed_reverbProperties[result].reflectionsPan[0]));
				SetWindowText(ed_reverbEditor.hWndReflectionsPanYValue, Str_VarArgs("%g", ed_reverbProperties[result].reflectionsPan[1]));
				SetWindowText(ed_reverbEditor.hWndReflectionsPanZValue, Str_VarArgs("%g", ed_reverbProperties[result].reflectionsPan[2]));

				SetWindowText(ed_reverbEditor.hWndLateReverbGainValue, Str_VarArgs("%g", ed_reverbProperties[result].lateReverbGain));
				SetWindowText(ed_reverbEditor.hWndLateReverbDelayValue, Str_VarArgs("%g", ed_reverbProperties[result].lateReverbDelay));
				SetWindowText(ed_reverbEditor.hWndLateReverbPanXValue, Str_VarArgs("%g", ed_reverbProperties[result].lateReverbPan[0]));
				SetWindowText(ed_reverbEditor.hWndLateReverbPanYValue, Str_VarArgs("%g", ed_reverbProperties[result].lateReverbPan[1]));
				SetWindowText(ed_reverbEditor.hWndLateReverbPanZValue, Str_VarArgs("%g", ed_reverbProperties[result].lateReverbPan[2]));

				SetWindowText(ed_reverbEditor.hWndEchoTimeValue, Str_VarArgs("%g", ed_reverbProperties[result].echoTime));
				SetWindowText(ed_reverbEditor.hWndEchoDepthValue, Str_VarArgs("%g", ed_reverbProperties[result].echoDepth));

				SetWindowText(ed_reverbEditor.hWndModulationTimeValue, Str_VarArgs("%g", ed_reverbProperties[result].modulationTime));
				SetWindowText(ed_reverbEditor.hWndModulationDepthValue, Str_VarArgs("%g", ed_reverbProperties[result].modulationDepth));

				SetWindowText(ed_reverbEditor.hWndHFReferenceValue, Str_VarArgs("%g", ed_reverbProperties[result].hfReference));
				SetWindowText(ed_reverbEditor.hWndLFReferenceValue, Str_VarArgs("%g", ed_reverbProperties[result].lfReference));

				SetWindowText(ed_reverbEditor.hWndAirAbsorptionGainHFValue, Str_VarArgs("%g", ed_reverbProperties[result].airAbsorptionGainHF));
				SetWindowText(ed_reverbEditor.hWndRoomRolloffFactorValue, Str_VarArgs("%g", ed_reverbProperties[result].roomRolloffFactor));

				break;
			}
		}

		break;
	}

	// Pass all unhandled messages to DefWindowProc
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

/*
 ==================
 ED_CreateReverbEditorWindow
 ==================
*/
bool ED_CreateReverbEditorWindow (void){

	WNDCLASSEX	wndClass;
	RECT		rect;
	int			screenWidth, screenHeight;
	int			x, y, w, h;
	int			i;

	// Center the window in the desktop
	screenWidth = GetSystemMetrics(SM_CXSCREEN);
	screenHeight = GetSystemMetrics(SM_CYSCREEN);

	rect.left = (screenWidth - 402) / 2;
	rect.top = (screenHeight - 518) / 2;
	rect.right = rect.left + 402;
	rect.bottom = rect.top + 518;

	AdjustWindowRectEx(&rect, REVERB_EDITOR_WINDOW_STYLE, FALSE, 0);

	x = rect.left;
	y = rect.top;
	w = rect.right - rect.left;
	h = rect.bottom - rect.top;

	// Register the frame class
	wndClass.cbSize = sizeof(WNDCLASSEX);
	wndClass.style = 0;
	wndClass.lpfnWndProc = ED_ReverbEditorWindowProc;
	wndClass.cbClsExtra = 0;
	wndClass.cbWndExtra = 0;
	wndClass.hInstance = sys.hInstance;
	wndClass.hIcon = LoadIcon(sys.hInstance, MAKEINTRESOURCE(IDI_ICON1));
	wndClass.hIconSm = 0;
	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
	wndClass.lpszMenuName = 0;
	wndClass.lpszClassName = REVERB_EDITOR_WINDOW_CLASS;

	if (!RegisterClassEx(&wndClass))
		return false;

	// Create the window
	ed_reverbEditor.hWnd = CreateWindowEx(0, REVERB_EDITOR_WINDOW_CLASS, REVERB_EDITOR_WINDOW_NAME, REVERB_EDITOR_WINDOW_STYLE, x, y, w, h, NULL, NULL, sys.hInstance, NULL);
	if (!ed_reverbEditor.hWnd){
		UnregisterClass(REVERB_EDITOR_WINDOW_CLASS, sys.hInstance);
		return false;
	}

	// Create the controls
	ed_reverbEditor.hWndFrame1 = CreateWindowEx(0, "BUTTON", "Environment", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 8, 48, 152, 64, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndFrame2 = CreateWindowEx(0, "BUTTON", "Reverberation", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 168, 48, 226, 64, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndFrame3 = CreateWindowEx(0, "BUTTON", "Decay", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 8, 120, 386, 64, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndFrame4 = CreateWindowEx(0, "BUTTON", "Reflections", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 8, 192, 386, 64, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndFrame5 = CreateWindowEx(0, "BUTTON", "Late Reverberation", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 8, 264, 386, 64, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndFrame6 = CreateWindowEx(0, "BUTTON", "Echo", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 8, 336, 188, 64, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndFrame7 = CreateWindowEx(0, "BUTTON", "Modulation", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 206, 336, 188, 64, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndFrame8 = CreateWindowEx(0, "BUTTON", "Reference Frequencies", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 8, 408, 188, 64, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndFrame9 = CreateWindowEx(0, "BUTTON", "", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 206, 408, 188, 64, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndArea = CreateWindowEx(0, "STATIC", "Map area:", WS_CHILD | WS_VISIBLE | SS_LEFT, 12, 11, 50, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndAreaValue = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE | SS_LEFT, 66, 11, 90, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndPreset = CreateWindowEx(0, "STATIC", "Reverb preset", WS_CHILD | WS_VISIBLE | SS_RIGHT, 172, 11, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndPresetValue = CreateWindowEx(0, "COMBOBOX", "", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWNLIST, 246, 8, 144, 200, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndDensity = CreateWindowEx(0, "STATIC", "Density", WS_CHILD | WS_VISIBLE | SS_CENTER, 12, 72, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndDensityValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 12, 88, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndDiffusion = CreateWindowEx(0, "STATIC", "Diffusion", WS_CHILD | WS_VISIBLE | SS_CENTER, 86, 72, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndDiffusionValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 86, 88, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndGain = CreateWindowEx(0, "STATIC", "Gain", WS_CHILD | WS_VISIBLE | SS_CENTER, 172, 72, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndGainValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 172, 88, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndGainHF = CreateWindowEx(0, "STATIC", "Gain HF", WS_CHILD | WS_VISIBLE | SS_CENTER, 246, 72, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndGainHFValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 246, 88, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndGainLF = CreateWindowEx(0, "STATIC", "Gain LF", WS_CHILD | WS_VISIBLE | SS_CENTER, 320, 72, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndGainLFValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 320, 88, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndDecayTime = CreateWindowEx(0, "STATIC", "Time", WS_CHILD | WS_VISIBLE | SS_CENTER, 12, 144, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndDecayTimeValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 12, 160, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndDecayHFRatio = CreateWindowEx(0, "STATIC", "HF Ratio", WS_CHILD | WS_VISIBLE | SS_CENTER, 86, 144, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndDecayHFRatioValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 86, 160, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndDecayLFRatio = CreateWindowEx(0, "STATIC", "LF Ratio", WS_CHILD | WS_VISIBLE | SS_CENTER, 160, 144, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndDecayLFRatioValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 160, 160, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndDecayHFLimit = CreateWindowEx(0, "BUTTON", "HF Limit", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX, 282, 146, 72, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndReflectionsGain = CreateWindowEx(0, "STATIC", "Gain", WS_CHILD | WS_VISIBLE | SS_CENTER, 12, 216, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndReflectionsGainValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 12, 232, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndReflectionsDelay = CreateWindowEx(0, "STATIC", "Delay", WS_CHILD | WS_VISIBLE | SS_CENTER, 86, 216, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndReflectionsDelayValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 86, 232, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndReflectionsPan = CreateWindowEx(0, "STATIC", "Panning", WS_CHILD | WS_VISIBLE | SS_CENTER, 172, 200, 218, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndReflectionsPanX = CreateWindowEx(0, "STATIC", "X", WS_CHILD | WS_VISIBLE | SS_CENTER, 172, 216, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndReflectionsPanY = CreateWindowEx(0, "STATIC", "Y", WS_CHILD | WS_VISIBLE | SS_CENTER, 246, 216, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndReflectionsPanZ = CreateWindowEx(0, "STATIC", "Z", WS_CHILD | WS_VISIBLE | SS_CENTER, 320, 216, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndReflectionsPanXValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 172, 232, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndReflectionsPanYValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 246, 232, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndReflectionsPanZValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 320, 232, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndLateReverbGain = CreateWindowEx(0, "STATIC", "Gain", WS_CHILD | WS_VISIBLE | SS_CENTER, 12, 288, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndLateReverbGainValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 12, 304, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndLateReverbDelay = CreateWindowEx(0, "STATIC", "Delay", WS_CHILD | WS_VISIBLE | SS_CENTER, 86, 288, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndLateReverbDelayValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 86, 304, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndLateReverbPan = CreateWindowEx(0, "STATIC", "Panning", WS_CHILD | WS_VISIBLE | SS_CENTER, 172, 272, 218, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndLateReverbPanX = CreateWindowEx(0, "STATIC", "X", WS_CHILD | WS_VISIBLE | SS_CENTER, 172, 288, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndLateReverbPanY = CreateWindowEx(0, "STATIC", "Y", WS_CHILD | WS_VISIBLE | SS_CENTER, 246, 288, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndLateReverbPanZ = CreateWindowEx(0, "STATIC", "Z", WS_CHILD | WS_VISIBLE | SS_CENTER, 320, 288, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndLateReverbPanXValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 172, 304, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndLateReverbPanYValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 246, 304, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndLateReverbPanZValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 320, 304, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndEchoTime = CreateWindowEx(0, "STATIC", "Time", WS_CHILD | WS_VISIBLE | SS_CENTER, 12, 360, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndEchoTimeValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 12, 376, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndEchoDepth = CreateWindowEx(0, "STATIC", "Depth", WS_CHILD | WS_VISIBLE | SS_CENTER, 122, 360, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndEchoDepthValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 122, 376, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndModulationTime = CreateWindowEx(0, "STATIC", "Time", WS_CHILD | WS_VISIBLE | SS_CENTER, 210, 360, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndModulationTimeValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 210, 376, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndModulationDepth = CreateWindowEx(0, "STATIC", "Depth", WS_CHILD | WS_VISIBLE | SS_CENTER, 320, 360, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndModulationDepthValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 320, 376, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndHFReference = CreateWindowEx(0, "STATIC", "HF", WS_CHILD | WS_VISIBLE | SS_CENTER, 12, 432, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndHFReferenceValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 12, 448, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndLFReference = CreateWindowEx(0, "STATIC", "LF", WS_CHILD | WS_VISIBLE | SS_CENTER, 122, 432, 70, 16, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndLFReferenceValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 122, 448, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndAirAbsorptionGainHF = CreateWindowEx(0, "STATIC", "Air Absorption Gain HF", WS_CHILD | WS_VISIBLE | SS_CENTER, 210, 416, 70, 32, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndAirAbsorptionGainHFValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 210, 448, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndRoomRolloffFactor = CreateWindowEx(0, "STATIC", "Room Rolloff Factor", WS_CHILD | WS_VISIBLE | SS_CENTER, 320, 416, 70, 32, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndRoomRolloffFactorValue = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_LEFT | ES_AUTOHSCROLL, 320, 448, 70, 20, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	ed_reverbEditor.hWndApply = CreateWindowEx(0, "BUTTON", "Apply", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 8, 485, 80, 25, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndReset = CreateWindowEx(0, "BUTTON", "Reset", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 92, 485, 80, 25, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndClear = CreateWindowEx(0, "BUTTON", "Clear", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 230, 485, 80, 25, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);
	ed_reverbEditor.hWndSave = CreateWindowEx(0, "BUTTON", "Save", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_CENTER | BS_VCENTER, 314, 485, 80, 25, ed_reverbEditor.hWnd, NULL, sys.hInstance, NULL);

	// Create and set the font
	ed_reverbEditor.hFont = CreateFont(14, 0, 0, 0, FW_LIGHT, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "MS Sans Serif");

	SendMessage(ed_reverbEditor.hWndFrame1, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndFrame2, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndFrame3, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndFrame4, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndFrame5, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndFrame6, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndFrame7, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndFrame8, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndFrame9, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndArea, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndAreaValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndPreset, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndPresetValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndDensity, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndDensityValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndDiffusion, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndDiffusionValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndGain, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndGainValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndGainHF, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndGainHFValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndGainLF, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndGainLFValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndDecayTime, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndDecayTimeValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndDecayHFRatio, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndDecayHFRatioValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndDecayLFRatio, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndDecayLFRatioValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndDecayHFLimit, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndReflectionsGain, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndReflectionsGainValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndReflectionsDelay, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndReflectionsDelayValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndReflectionsPan, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndReflectionsPanX, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndReflectionsPanY, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndReflectionsPanZ, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndReflectionsPanXValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndReflectionsPanYValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndReflectionsPanZValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndLateReverbGain, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndLateReverbGainValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndLateReverbDelay, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndLateReverbDelayValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndLateReverbPan, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndLateReverbPanX, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndLateReverbPanY, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndLateReverbPanZ, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndLateReverbPanXValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndLateReverbPanYValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndLateReverbPanZValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndEchoTime, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndEchoTimeValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndEchoDepth, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndEchoDepthValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndModulationTime, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndModulationTimeValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndModulationDepth, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndModulationDepthValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndHFReference, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndHFReferenceValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndLFReference, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndLFReferenceValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndAirAbsorptionGainHF, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndAirAbsorptionGainHFValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndRoomRolloffFactor, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndRoomRolloffFactorValue, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	SendMessage(ed_reverbEditor.hWndApply, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndReset, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndClear, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);
	SendMessage(ed_reverbEditor.hWndSave, WM_SETFONT, (WPARAM)ed_reverbEditor.hFont, FALSE);

	// Fill preset combo box
	SendMessage(ed_reverbEditor.hWndPresetValue, CB_ADDSTRING, 0, (LPARAM)"Custom");

	for (i = 0; i < 26; i++)
		SendMessage(ed_reverbEditor.hWndPresetValue, CB_ADDSTRING, 0, (LPARAM)ed_reverbNames[i]);

	// Show the window
	ShowWindow(ed_reverbEditor.hWnd, SW_SHOW);
	UpdateWindow(ed_reverbEditor.hWnd);
	SetForegroundWindow(ed_reverbEditor.hWnd);
	SetFocus(ed_reverbEditor.hWnd);

	return true;
}

/*
 ==================
 ED_DestroyReverbEditorWindow
 ==================
*/
void ED_DestroyReverbEditorWindow (void){

	if (!ed_reverbEditor.hWnd)
		return;

	if (ed_reverbEditor.hFont)
		DeleteObject(ed_reverbEditor.hFont);

	ShowWindow(ed_reverbEditor.hWnd, SW_HIDE);
	DestroyWindow(ed_reverbEditor.hWnd);
	UnregisterClass(REVERB_EDITOR_WINDOW_CLASS, sys.hInstance);

	memset(&ed_reverbEditor, 0, sizeof(reverbEditor_t));
}

/*
 ==================
 ED_SetReverbCallbacks
 ==================
*/
void ED_SetReverbCallbacks (reverbCallbacks_t *callbacks){

	if (!ed_reverbEditor.hWnd)
		return;

	ed_reverbEditor.callbacks.Update = callbacks->Update;
	ed_reverbEditor.callbacks.Clear = callbacks->Clear;
	ed_reverbEditor.callbacks.Save = callbacks->Save;
	ed_reverbEditor.callbacks.Close = callbacks->Close;
}

/*
 ==================
 ED_EditReverbProperties
 ==================
*/
void ED_EditReverbProperties (int index, reverbProperties_t *properties){

	int		i;

	if (!ed_reverbEditor.hWnd)
		return;

	// Apply current reverb properties
	ED_ApplyReverbProperties();

	// Set the current reverb properties
	if (properties){
		ed_reverbEditor.enabled = true;

		ed_reverbEditor.editIndex = index;
		ed_reverbEditor.editProperties = *properties;
	}
	else {
		ed_reverbEditor.enabled = false;

		properties = &ed_reverbProperties[REVERB_PRESET_GENERIC];
	}

	// Update the controls
	SetWindowText(ed_reverbEditor.hWndAreaValue, Str_VarArgs("%i", index));

	for (i = 0; i < 26; i++){
		if (properties->density != ed_reverbProperties[i].density)
			continue;
		if (properties->diffusion != ed_reverbProperties[i].diffusion)
			continue;
		if (properties->gain != ed_reverbProperties[i].gain)
			continue;
		if (properties->gainHF != ed_reverbProperties[i].gainHF)
			continue;
		if (properties->gainLF != ed_reverbProperties[i].gainLF)
			continue;
		if (properties->decayTime != ed_reverbProperties[i].decayTime)
			continue;
		if (properties->decayHFRatio != ed_reverbProperties[i].decayHFRatio)
			continue;
		if (properties->decayLFRatio != ed_reverbProperties[i].decayLFRatio)
			continue;
		if (properties->decayHFLimit != ed_reverbProperties[i].decayHFLimit)
			continue;
		if (properties->reflectionsGain != ed_reverbProperties[i].reflectionsGain)
			continue;
		if (properties->reflectionsDelay != ed_reverbProperties[i].reflectionsDelay)
			continue;
		if (properties->reflectionsPan != ed_reverbProperties[i].reflectionsPan)
			continue;
		if (properties->lateReverbGain != ed_reverbProperties[i].lateReverbGain)
			continue;
		if (properties->lateReverbDelay != ed_reverbProperties[i].lateReverbDelay)
			continue;
		if (properties->lateReverbPan != ed_reverbProperties[i].lateReverbPan)
			continue;
		if (properties->echoTime != ed_reverbProperties[i].echoTime)
			continue;
		if (properties->echoDepth != ed_reverbProperties[i].echoDepth)
			continue;
		if (properties->modulationTime != ed_reverbProperties[i].modulationTime)
			continue;
		if (properties->modulationDepth != ed_reverbProperties[i].modulationDepth)
			continue;
		if (properties->hfReference != ed_reverbProperties[i].hfReference)
			continue;
		if (properties->lfReference != ed_reverbProperties[i].lfReference)
			continue;
		if (properties->airAbsorptionGainHF != ed_reverbProperties[i].airAbsorptionGainHF)
			continue;
		if (properties->roomRolloffFactor != ed_reverbProperties[i].roomRolloffFactor)
			continue;

		break;
	}
	if (i == 26)
		SendMessage(ed_reverbEditor.hWndPresetValue, CB_SETCURSEL, (WPARAM)0, 0);
	else
		SendMessage(ed_reverbEditor.hWndPresetValue, CB_SETCURSEL, (WPARAM)(i+1), 0);

	SetWindowText(ed_reverbEditor.hWndDensityValue, Str_VarArgs("%g", properties->density));
	SetWindowText(ed_reverbEditor.hWndDiffusionValue, Str_VarArgs("%g", properties->diffusion));

	SetWindowText(ed_reverbEditor.hWndGainValue, Str_VarArgs("%g", properties->gain));
	SetWindowText(ed_reverbEditor.hWndGainHFValue, Str_VarArgs("%g", properties->gainHF));
	SetWindowText(ed_reverbEditor.hWndGainLFValue, Str_VarArgs("%g", properties->gainLF));

	SetWindowText(ed_reverbEditor.hWndDecayTimeValue, Str_VarArgs("%g", properties->decayTime));
	SetWindowText(ed_reverbEditor.hWndDecayHFRatioValue, Str_VarArgs("%g", properties->decayHFRatio));
	SetWindowText(ed_reverbEditor.hWndDecayLFRatioValue, Str_VarArgs("%g", properties->decayLFRatio));

	if (properties->decayHFLimit)
		SendMessage(ed_reverbEditor.hWndDecayHFLimit, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
	else
		SendMessage(ed_reverbEditor.hWndDecayHFLimit, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); 

	SetWindowText(ed_reverbEditor.hWndReflectionsGainValue, Str_VarArgs("%g", properties->reflectionsGain));
	SetWindowText(ed_reverbEditor.hWndReflectionsDelayValue, Str_VarArgs("%g", properties->reflectionsDelay));
	SetWindowText(ed_reverbEditor.hWndReflectionsPanXValue, Str_VarArgs("%g", properties->reflectionsPan[0]));
	SetWindowText(ed_reverbEditor.hWndReflectionsPanYValue, Str_VarArgs("%g", properties->reflectionsPan[1]));
	SetWindowText(ed_reverbEditor.hWndReflectionsPanZValue, Str_VarArgs("%g", properties->reflectionsPan[2]));

	SetWindowText(ed_reverbEditor.hWndLateReverbGainValue, Str_VarArgs("%g", properties->lateReverbGain));
	SetWindowText(ed_reverbEditor.hWndLateReverbDelayValue, Str_VarArgs("%g", properties->lateReverbDelay));
	SetWindowText(ed_reverbEditor.hWndLateReverbPanXValue, Str_VarArgs("%g", properties->lateReverbPan[0]));
	SetWindowText(ed_reverbEditor.hWndLateReverbPanYValue, Str_VarArgs("%g", properties->lateReverbPan[1]));
	SetWindowText(ed_reverbEditor.hWndLateReverbPanZValue, Str_VarArgs("%g", properties->lateReverbPan[2]));

	SetWindowText(ed_reverbEditor.hWndEchoTimeValue, Str_VarArgs("%g", properties->echoTime));
	SetWindowText(ed_reverbEditor.hWndEchoDepthValue, Str_VarArgs("%g", properties->echoDepth));

	SetWindowText(ed_reverbEditor.hWndModulationTimeValue, Str_VarArgs("%g", properties->modulationTime));
	SetWindowText(ed_reverbEditor.hWndModulationDepthValue, Str_VarArgs("%g", properties->modulationDepth));

	SetWindowText(ed_reverbEditor.hWndHFReferenceValue, Str_VarArgs("%g", properties->hfReference));
	SetWindowText(ed_reverbEditor.hWndLFReferenceValue, Str_VarArgs("%g", properties->lfReference));

	SetWindowText(ed_reverbEditor.hWndAirAbsorptionGainHFValue, Str_VarArgs("%g", properties->airAbsorptionGainHF));
	SetWindowText(ed_reverbEditor.hWndRoomRolloffFactorValue, Str_VarArgs("%g", properties->roomRolloffFactor));

	// Enable or disable the controls
	EnableWindow(ed_reverbEditor.hWndFrame1, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndFrame2, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndFrame3, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndFrame4, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndFrame5, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndFrame6, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndFrame7, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndFrame8, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndFrame9, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndArea, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndAreaValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndPreset, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndPresetValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndDensity, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndDensityValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndDiffusion, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndDiffusionValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndGain, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndGainValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndGainHF, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndGainHFValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndGainLF, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndGainLFValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndDecayTime, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndDecayTimeValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndDecayHFRatio, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndDecayHFRatioValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndDecayLFRatio, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndDecayLFRatioValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndDecayHFLimit, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndReflectionsGain, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndReflectionsGainValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndReflectionsDelay, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndReflectionsDelayValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndReflectionsPan, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndReflectionsPanX, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndReflectionsPanY, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndReflectionsPanZ, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndReflectionsPanXValue, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndReflectionsPanYValue, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndReflectionsPanZValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndLateReverbGain, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndLateReverbGainValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndLateReverbDelay, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndLateReverbDelayValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndLateReverbPan, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndLateReverbPanX, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndLateReverbPanY, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndLateReverbPanZ, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndLateReverbPanXValue, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndLateReverbPanYValue, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndLateReverbPanZValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndEchoTime, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndEchoTimeValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndEchoDepth, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndEchoDepthValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndModulationTime, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndModulationTimeValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndModulationDepth, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndModulationDepthValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndHFReference, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndHFReferenceValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndLFReference, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndLFReferenceValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndAirAbsorptionGainHF, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndAirAbsorptionGainHFValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndRoomRolloffFactor, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndRoomRolloffFactorValue, ed_reverbEditor.enabled);

	EnableWindow(ed_reverbEditor.hWndApply, ed_reverbEditor.enabled);
	EnableWindow(ed_reverbEditor.hWndReset, ed_reverbEditor.enabled);
}
